package game.test.server;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.util.ArrayList;

public class Server implements Runnable {
	public static final String DATA_SEPARATOR = "|";

	// Client packets
	public static final String CLIENT_INFO = "CLIENT_INFO";
	public static final String CLIENT_DISCONNECT = "CLIENT_DISCONNECT";
	public static final String CLIENT_SETPOS = "CLIENT_SETPOS";

	// Server packets
	public static final String SERVER_STOP = "SERVER_STOP";
	public static final String SERVER_ACCEPT = "SERVER_ACCEPT";

	public boolean running = false;
	private ServerSocket server;
	private Thread thread, listenThread;

	private int port = 8755;
	private BufferedReader br = new BufferedReader(new InputStreamReader(
			System.in));

	private ArrayList<Client> clients = new ArrayList<Client>();

	private void init() {
		System.out.println("Enter port");
		try {
			port = Integer.parseInt(br.readLine());
		} catch (Exception e) {
			e.printStackTrace();
		}

		System.out.println("Starting new server on port " + port);
		try {
			server = new ServerSocket(port);
		} catch (IOException e) {
			e.printStackTrace();
		}
		startListening();
		Thread cin = new Thread(new Runnable() {
			public void run() {
				try {
					String s = br.readLine();
					if (s.toLowerCase().equals("/stop")) {
						System.out.println("Stopping the server");
						stop();
					}
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		});
		cin.start();
	}

	private void update() {
		
	}

	public void process(Client c, String data) {
		String d[] = data.split(DATA_SEPARATOR);
		switch (d[0]) {
		case SERVER_STOP:
			stop();
			break;
		case CLIENT_INFO:
			c.setName(d[1]);
			sendToAll(CLIENT_INFO + DATA_SEPARATOR + d[1]);
			break;
		}
	}

	private void sendToAll(String data) {
		for (int i = 0; i < clients.size(); i++) {
			clients.get(i).send(data);
		}
	}

	private void startListening() {
		listenThread = new Thread(new Runnable() {
			public void run() {
				while (running) {
					Socket s = null;
					try {
						s = server.accept();
					} catch (IOException e) {
						continue;
					}

					addClient(s);
				}
			}
		});
		listenThread.start();
	}

	public void run() {
		init();
		while (running) {
			update();
			try {
				Thread.sleep(1);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}

	private void start() {
		running = true;
		thread = new Thread(this);
		thread.start();
	}

	private void disconnect() {
		for (int i = 0; i < clients.size(); i++) {
			clients.get(i).send(Server.CLIENT_DISCONNECT);
			clients.get(i).disconnect();
		}
		try {
			server.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	private void stop() {
		running = false;
		disconnect();
		try {
			thread.join();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}

	public void addClient(Socket s) {
		clients.add(new Client(s, this));
	}

	public void removeClient(Client c) {
		clients.remove(c);
	}

	public static void main(String[] args) {
		Server server = new Server();

		server.start();
	}
}
